#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "my_gui.h"

#include "gps_location.h"

LV_FONT_DECLARE(gbk2312);
LV_FONT_DECLARE(gbk2312_16);
LV_FONT_DECLARE(gbk2312_18);
LV_FONT_DECLARE(gbk2312_20);
LV_FONT_DECLARE(gbk2312_30);
LV_IMG_DECLARE(world);

#define LV_TICK_PERIOD_MS   1 
#define TITLE_WIN_SIZE       20
static void hashimLGB_lvgl_gui(void);
static void lv_tick_task(void* arg);
char* set_text_color(uint32_t color, const char* text);
SemaphoreHandle_t xGuiSemaphore;

lv_obj_t* SN_label;
/**
 * @brief 初始化显示任务
 *
 * @param arg
 */
void app_lvgl_display_task(void* arg)
{

    xGuiSemaphore = xSemaphoreCreateMutex();
    lv_init();
    lvgl_driver_init();
    lv_color_t* buf1 = heap_caps_malloc(DISP_BUF_SIZE * sizeof(lv_color_t), MALLOC_CAP_DMA);
    assert(buf1 != NULL);
    lv_color_t* buf2 = heap_caps_malloc(DISP_BUF_SIZE * sizeof(lv_color_t), MALLOC_CAP_DMA);
    assert(buf2 != NULL);
    static lv_disp_buf_t disp_buf;
    uint32_t size_in_px = DISP_BUF_SIZE;
    /* Initialize the working buffer depending on the selected display.
     * NOTE: buf2 == NULL when using monochrome displays. */
    lv_disp_buf_init(&disp_buf, buf1, buf2, size_in_px);
    lv_disp_drv_t disp_drv;
    lv_disp_drv_init(&disp_drv);
    disp_drv.flush_cb = disp_driver_flush;
#ifdef CONFIG_LV_TFT_DISPLAY_MONOCHROME
    disp_drv.rounder_cb = disp_driver_rounder;
    disp_drv.set_px_cb = disp_driver_set_px;
#endif
    disp_drv.buffer = &disp_buf;

    lv_disp_drv_register(&disp_drv);

    const esp_timer_create_args_t periodic_timer_args = {
       .callback = &lv_tick_task,
       .name = "periodic_gui"
    };
    esp_timer_handle_t periodic_timer;
    ESP_ERROR_CHECK(esp_timer_create(&periodic_timer_args, &periodic_timer));
    ESP_ERROR_CHECK(esp_timer_start_periodic(periodic_timer, LV_TICK_PERIOD_MS * 1000));

    hashimLGB_lvgl_gui();

    while (1) {
        /* Delay 1 tick (assumes FreeRTOS tick is 10ms */
        vTaskDelay(pdMS_TO_TICKS(20));

        if (pdTRUE == xSemaphoreTake(xGuiSemaphore, portMAX_DELAY)) {
            lv_task_handler();
            xSemaphoreGive(xGuiSemaphore);
        }

        switch (EC_AT_FLAG)
        {
            case AT_GET_SN_OK:
                lv_label_set_text(SN_label, SIM_SN);
                lv_obj_set_pos(SN_label, 30, 220);
                break;
            default:
                break;
        }
    }
    /* A task should NEVER return */
    free(buf1);
    free(buf2);
    vTaskDelete(NULL);
}

/**
 * @brief 初始化显示
 *
 */
static void hashimLGB_lvgl_gui(void)
{
    //显示北京图片
    lv_obj_t* img = lv_img_create(lv_scr_act(), NULL);
    lv_img_set_src(img, &world);

    /**
     * @brief 新建一个屏幕并设置样式
     *
     */

    lv_obj_t* screen1 = lv_obj_get_screen(img);
    lv_obj_set_size(screen1, 240, 240);

    lv_obj_t* canvers1 = lv_obj_create(screen1, NULL);
    static lv_style_t screen1_style;
    lv_style_set_bg_color(&screen1_style, LV_STATE_DEFAULT, LV_COLOR_BLACK);
    lv_style_set_bg_opa(&screen1_style, LV_STATE_DEFAULT, 60);

    lv_obj_set_size(canvers1, 240, 240);
    lv_obj_add_style(canvers1, LV_LABEL_PART_MAIN, &screen1_style);

    /**
    * @brief 创建经度标签
    *
    */
    static lv_style_t label1_style;
    lv_obj_t* label1;
    lv_style_init(&label1_style);
    lv_style_set_text_font(&label1_style, LV_STATE_DEFAULT, &gbk2312_30);
    lv_style_set_text_color(&label1_style, LV_STATE_DEFAULT, LV_COLOR_USER1);
    // lv_style_set_text_opa(&label1_style, LV_STATE_DEFAULT, 98);
    label1 = lv_label_create(canvers1, NULL);
    lv_label_set_recolor(label1, true);
    lv_label_set_text(label1, "经度:");
    lv_obj_set_pos(label1, 0, 30);
    lv_obj_add_style(label1, LV_LABEL_PART_MAIN, &label1_style);
    /**
     * @brief 创建纬度标签
     *
     */
    lv_obj_t* label2;
    label2 = lv_label_create(canvers1, label1);
    lv_label_set_recolor(label2, true);
    lv_label_set_text(label2, "纬度:");
    lv_obj_set_pos(label2, 0, 90);

    /**
   * @brief 创建海拔标签
   *
   */
    lv_obj_t* label3;
    label3 = lv_label_create(canvers1, label1);
    lv_label_set_recolor(label3, true);
    lv_label_set_text(label3, "海拔:");
    lv_obj_set_pos(label3, 0, 150);

    /**
     * @brief 创建 SN 号标签
     *
     */
    lv_style_t SN_label_style;
    lv_style_init(&SN_label_style);
    lv_style_set_text_font(&SN_label_style, LV_STATE_DEFAULT, LV_FONT_MONTSERRAT_10);
    lv_style_set_text_color(&SN_label_style, LV_STATE_DEFAULT, LV_COLOR_WHITE);

    lv_obj_t* SN_label_tite = lv_label_create(canvers1, NULL);
    lv_label_set_text(SN_label_tite, "SN:");
    lv_obj_set_pos(SN_label_tite, 2, 220);
    SN_label = lv_label_create(canvers1, SN_label_tite);
}
/**
 * @brief
 *
 * @param arg
 */
static void lv_tick_task(void* arg) {
    (void)arg;

    lv_tick_inc(LV_TICK_PERIOD_MS);
}
